﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using WcfContract;
using System.Diagnostics;
using System.IO;

namespace TestClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("CLR Version: " + System.Environment.Version.ToString());
            ServiceCallback callback = new ServiceCallback();

            IServiceBufferedContract bufferedPipesChannel = null;
            Console.WriteLine("Create Buffered Pipe Channel");
            try
            {
                NetNamedPipeBinding binding = new NetNamedPipeBinding();
                binding.TransferMode = TransferMode.Buffered;
                binding.Security.Mode = NetNamedPipeSecurityMode.None;
                EndpointAddress endpoint = new EndpointAddress("net.pipe://localhost/TestServer/ServiceBuffered");

                DuplexChannelFactory<IServiceBufferedContract> factory = new DuplexChannelFactory<IServiceBufferedContract>(callback, binding, endpoint);
                bufferedPipesChannel = factory.CreateChannel();
                Console.WriteLine("Buffered Pipe Channel Created - try to establish");

                bufferedPipesChannel.SimpleFunctionCall();
                Console.WriteLine("Buffered Pipe Channel Established");
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to Create/Establish Buffered Pipe Channel");
                Console.WriteLine(e.ToString());
                Console.WriteLine();
            }


            IServiceBufferedContract bufferedTcpChannel = null;
            Console.WriteLine("Create Buffered TCP Channel");
            try
            {
                NetTcpBinding binding = new NetTcpBinding();
                binding.TransferMode = TransferMode.Buffered;
                binding.Security.Mode = SecurityMode.None;
                EndpointAddress endpoint = new EndpointAddress("net.tcp://localhost/TestServer/ServiceBuffered");

                DuplexChannelFactory<IServiceBufferedContract> factory = new DuplexChannelFactory<IServiceBufferedContract>(callback, binding, endpoint);
                bufferedTcpChannel = factory.CreateChannel();
                Console.WriteLine("Buffered TCP Channel Created - try to establish");

                bufferedTcpChannel.SimpleFunctionCall();
                Console.WriteLine("Buffered TCP Channel Established");
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to Create/Establish Buffered TCP Channel");
                Console.WriteLine(e.ToString());
                Console.WriteLine();
            }

 
            /*

            DuplexChannelFactory<IServiceBufferedContract> factoryServiceBuffered = new DuplexChannelFactory<IServiceBufferedContract>(callback, bufferedTcpBinding, bufferedEndpoint);


            NetNamedPipeBinding streamedBinding = new NetNamedPipeBinding();
            streamedBinding.TransferMode = TransferMode.Streamed;

            EndpointAddress streamedEndpoint = new EndpointAddress("net.pipe://localhost/TestServer/ServiceStreamed");

            ChannelFactory<IServiceStreamedContract> factoryServiceStreamed = new ChannelFactory<IServiceStreamedContract>(streamedBinding, streamedEndpoint);
            Console.WriteLine("Client Running");

            IServiceStreamedContract channelServiceStreamed = factoryServiceStreamed.CreateChannel();

            
            IServiceBufferedContract channelServceBuffered = factoryServiceBuffered.CreateChannel();
            byte[] data = new byte[10000];

            /*
            Stream stream = channelServiceStreamed.Test();

            stream.Read(data, 0, data.Length);

            stream.Close();

             */
            if( bufferedTcpChannel != null ) TestBuffered("Test Buffered TCP Channel", bufferedTcpChannel,1000, 1000);
            if (bufferedPipesChannel != null) TestBuffered("Test Buffered Pipes Channel", bufferedPipesChannel,1000, 1000);


            Console.WriteLine("Tests Finished, press any key to stop...");
            Console.ReadKey();
        }

        private static void TestBuffered(string description, IServiceBufferedContract channel, int iterations, int buffersize)
        {

            Console.WriteLine(description +": " + iterations.ToString() + " Iterations, " + buffersize.ToString() + " Buffer Size" );
            byte[] data = new byte[buffersize];

            Stopwatch watch = new Stopwatch();
            watch.Start();
            for (int i = 0; i < iterations; ++i)
            {
                channel.SimpleFunctionCall();
            }
            watch.Stop();
            Console.WriteLine("  SimpleFunction Call Time: " + watch.ElapsedMilliseconds.ToString());

            Console.WriteLine("  One Way Send");
            watch.Reset();
            watch.Start();
            for (int i = 0; i < iterations; ++i)
            {
                channel.OneWay(data);
            }
            watch.Stop();
            Console.WriteLine("  One Way Send Elapsed Time: " + watch.ElapsedMilliseconds.ToString());


            Console.WriteLine("  Recceive");
            watch.Reset();
            watch.Start();
            for (int i = 0; i < iterations; ++i)
            {
                channel.Recceive();
            }
            watch.Stop();
            Console.WriteLine("  Recceive Elapsed Time: " + watch.ElapsedMilliseconds.ToString());

            watch.Reset();
            watch.Start();
            for (int i = 0; i < iterations; ++i)
            {
                channel.Test(data, 0);
            }
            watch.Stop();
            Console.WriteLine("  No Callbacks Elapsed Time: " + watch.ElapsedMilliseconds.ToString());

            Console.WriteLine("  Callbacks");
            watch.Reset();
            watch.Start();
            channel.Test(data, iterations);
            watch.Stop();
            Console.WriteLine("  Callbacks Elapsed Time: " + watch.ElapsedMilliseconds.ToString());
        }
    }
}
